﻿using Bandit.Helpers;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Windows;

namespace MartiniDisplayAOI
{
    /// <summary>
    /// App.xaml 的交互逻辑
    /// </summary>
    public partial class App : Application
    {
        System.Threading.Mutex _Mutex;

        /// <summary>
        /// 设置窗体视图模型
        /// </summary>
        public static ViewModels.SettingViewModel SettingViewModel { get; private set; }

        /// <summary>
        /// 主窗体视图模型
        /// </summary>
        public static ViewModels.MainViewModel MainViewModel { get; private set; }

        public App()
        {
            #region 未捕获异常处理
            DispatcherUnhandledException += (sender, e) =>
            {
                LogHelper.Error(e.Exception, "DispatcherUnhandledException");

                e.Handled = true;

                if (Bandit.UI.BanditDialog.Show(App.GetString("UnhandledExceptionPrompt"), App.GetString("Prompt"), MessageBoxButton.YesNo, Bandit.UI.DialogIcon.Shame) == MessageBoxResult.No)
                {
                    this.Shutdown();
                }
            };

            AppDomain.CurrentDomain.UnhandledException += (sender, e) =>
            {
                Exception ex = e.ExceptionObject as Exception;

                LogHelper.Error(ex, "UnhandledException");

                Dispatcher.Invoke((Action)delegate
                {
                    Bandit.UI.BanditDialog.Show(App.GetString("ExceptionExitPrompt") + Environment.NewLine + ex.GetMessage(), App.GetString("Prompt"), MessageBoxButton.OK, Bandit.UI.DialogIcon.Shame);
                });
            };
            #endregion

            #region App Exit

            this.Exit += delegate
            {
                LogHelper.Info("Application Exit!");
            };

            #endregion

            #region App Startup

            this.Startup += delegate
            {
                #region 限制多开
                bool ret;

                string name = System.Reflection.Assembly.GetExecutingAssembly().FullName.Split(new char[] { ',' })[0];

                _Mutex = new System.Threading.Mutex(true, name, out ret);
                if (!ret)
                {
                    Environment.Exit(0);
                }
                #endregion

                LogHelper.Info(string.Format("*** Application Run! {0} V{1} ***", this.GetAssemblyName(), this.GetVersion()));

                if (Environment.OSVersion.Version.Major < 6)
                {
                    System.Windows.Media.RenderOptions.ProcessRenderMode = System.Windows.Interop.RenderMode.SoftwareOnly;
                }

                SettingViewModel = new ViewModels.SettingViewModel();

                MainViewModel = new ViewModels.MainViewModel();

                if (System.IO.File.Exists(AppDomain.CurrentDomain.BaseDirectory + "Bandit.Updater.exe"))
                {
                    try
                    {
                        System.IO.File.Delete(AppDomain.CurrentDomain.BaseDirectory + "Bandit.Updater.exe");
                    }
                    catch
                    {
                        System.Diagnostics.Debug.WriteLine("Delete Bandit.Updater.exe");
                    }
                }
            };

            #endregion
        }

        #region 检查更新

        /// <summary>
        /// 检查更新
        /// </summary>
        /// <returns></returns>
        public static bool CheckUpdate()
        {
            bool result = false;

            string serverAddress = "http://10.90.6.21";

            string assembly = Application.ResourceAssembly.GetName().Name;

            string url = string.Format("{0}/Api/Software/FindByAssemblyName", serverAddress);

            HttpRequestItem requestItem = new HttpRequestItem(url);

            requestItem.RequestCount = 3;

            requestItem.Method = "POST";

            requestItem.RequestPayload = "{" + string.Format("\"AssemblyName\":\"{0}\"", assembly) + "}";

            try
            {
                HttpHelper http = new HttpHelper();

                HttpResponseResult responseResponse = http.HttpRequest(requestItem);
                if (responseResponse.Content.GetBetweenValue("Code\":", ",") == "0")
                {
                    Version ver = new Version(responseResponse.Content.GetBetweenValue("VersionName\":\"", "\""));

                    if (ver.CompareTo(Application.ResourceAssembly.GetName().Version) == 1)
                    {
                        result = true;

                        if (App.Current.ShowDialog("检测到有新版本，是否更新？", "提示", MessageBoxButton.YesNo, Bandit.UI.DialogIcon.QuestionFace) == MessageBoxResult.Yes)
                        {
                            if (DownloadUpdater(string.Format("{0}/Softwares/Bandit.Updater.exe", serverAddress), "Bandit.Updater.exe"))
                            {
                                string softwareUrl = string.Format("{0}/{1}", serverAddress, responseResponse.Content.GetBetweenValue("Url\":\"", "\""));
                                string softwareName = string.Empty.GetBaseDirectory() + responseResponse.Content.GetBetweenValue("SoftwareName\":\"", "\"");

                                string[] args = new string[3]
                                {
                                    softwareUrl,
                                    softwareName,
                                    Application.ResourceAssembly.GetName().Name + ".exe"
                                };

                                Bandit.Helpers.ToolsHelper.ExecProcess(AppDomain.CurrentDomain.BaseDirectory + @"Bandit.Updater.exe", args, false);

                                Environment.Exit(0);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error(ex, "CheckUpdate");
            }

            return result;
        }

        #endregion

        #region 下载更新器
        /// <summary>
        /// 下载更新器
        /// </summary>
        /// <param name="url"></param>
        /// <param name="softwareName"></param>
        /// <returns></returns>
        private static bool DownloadUpdater(string url, string softwareName)
        {
            bool result = false;
            try
            {
                System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(new Uri(url));

                //“听说”在这加一句垃圾回收，可以解决超时问题...
                System.GC.Collect();

                using (System.Net.HttpWebResponse response = (System.Net.HttpWebResponse)request.GetResponse())
                {
                    using (var stream = response.GetResponseStream())
                    {
                        byte[] buffer = new byte[4096];

                        int len = 0;

                        using (System.IO.FileStream fs = new System.IO.FileStream(string.Empty.GetBaseDirectory() + softwareName, System.IO.FileMode.Create, System.IO.FileAccess.Write))
                        {
                            while ((len = stream.Read(buffer, 0, buffer.Length)) > 0)
                            {
                                fs.Write(buffer, 0, len);
                            }
                            fs.Dispose();
                            fs.Close();
                        }
                        stream.Close();
                    }

                    response.Close();
                }

                result = true;
            }
            catch (Exception ex)
            {
                Bandit.Helpers.LogHelper.Error(ex, string.Format("{0}", url));
            }
            finally
            {
                System.GC.Collect();
            }

            return result;
        }
        #endregion

        #region 变更语言
        /// <summary>
        /// 变更语言
        /// </summary>
        /// <param name="language"></param>
        public static void ChangeLanguage(string language)
        {
            string languageFile = AppDomain.CurrentDomain.BaseDirectory + @"Language\" + language + ".xaml";

            if (!System.IO.File.Exists(languageFile))
            {
                string languageCode = System.Globalization.CultureInfo.InstalledUICulture.Name;
                string message = "The selected language file is missing. Please contact relevant personnel.";
                string title = "Prompt";
                switch (languageCode)
                {
                    case "zh-CN":
                        message = "所选择的语言文件丢失，请联系相关人员";
                        title = "提示";
                        break;
                    case "zh-TW":
                        message = "所選擇的語言文件丟失，請聯繫相關人員";
                        title = "提示";
                        break;
                    default:
                        break;
                }

                Bandit.UI.BanditDialog.Show(message, title, MessageBoxButton.OK, Bandit.UI.DialogIcon.Information);
                return;
            }

            foreach (ResourceDictionary rd in App.Current.Resources.MergedDictionaries)
            {
                if (rd.Source.OriginalString.ToLower().Contains(@"language/") || rd.Source.OriginalString.ToLower().Contains(@"\language\"))
                {
                    rd.Source = new Uri(languageFile);
                    return;
                }
            }

            App.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri(languageFile) });
        }
        #endregion

        #region 变更主题
        /// <summary>
        /// 切换主题
        /// </summary>
        /// <param name="theme"></param>
        public static void ChangeTheme(string theme)
        {
            string themeFile = AppDomain.CurrentDomain.BaseDirectory + @"Theme\" + theme + ".xaml";

            if (!System.IO.File.Exists(themeFile))
            {
                Bandit.UI.BanditDialog.Show(App.GetString("ThemeMissPrompt"), App.GetString("Prompt"), MessageBoxButton.OK, Bandit.UI.DialogIcon.Information);
                return;
            }

            foreach (ResourceDictionary rd in App.Current.Resources.MergedDictionaries)
            {
                if (rd.Source.OriginalString.ToLower().Contains(@"theme/") || rd.Source.OriginalString.ToLower().Contains(@"\theme\"))
                {
                    rd.Source = new Uri(themeFile);
                    return;
                }
            }

            App.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri(themeFile) });
        }
        #endregion

        #region 获取字符串资源
        /// <summary>
        /// 获取字符串资源
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string GetString(string key)
        {
            var resource = App.Current.Resources.MergedDictionaries.FirstOrDefault(s => s.Source.OriginalString.ToLower().Contains(@"language/") || s.Source.OriginalString.ToLower().Contains(@"\language\"));

            if (resource != null)
            {
                object value = resource[key];

                if (value != null)
                {
                    return value.ToString();
                }
            }

            return null;
        }

        #endregion
    }
}
